<template>
  <div>
    <el-dialog :before-close="cancelPick" :title="title" :visible.sync="open" append-to-body width="90%">
      <el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-position="middle"
               label-width="100px" size="small"
      >
        <el-form-item label="样本复份编号" prop="sampBackupCode">
          <el-input
            v-model="queryParams.sampBackupCode"
            clearable
            placeholder="请输入样本复份编号"
            size="small"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="样本类型" prop="sampTypeId">
          <treeselect v-model="queryParams.sampTypeId" :normalizer="normalizerSampType" :options="sampleTypeOptions"
                      placeholder="请选择样本类型" size="small" style="width: 220px"
          />
        </el-form-item>
        <el-form-item label="样本组" prop="sampGroupId">
          <treeselect v-model="queryParams.sampGroupId" :normalizer="normalizerSampGroup" :options="sampleGroupOptions"
                      placeholder="请选择样本组" size="small" style="width: 220px"
          />
        </el-form-item>
        <el-form-item label="条码/二维码" prop="qrCode">
          <el-input
            v-model="queryParams.qrCode"
            clearable
            placeholder="样本条码/二维码"
            size="small"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="样本源编号" prop="sourceCode">
          <el-input
            v-model="queryParams.sourceCode"
            clearable
            placeholder="请输入样本源编号"
            size="small"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="样本源名称" prop="sourceName">
          <el-input
            v-model="queryParams.sourceName"
            clearable
            placeholder="请输入样本源名称"
            size="small"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="样本源类型" prop="sourceTypeId">
          <treeselect v-model="queryParams.sourceTypeId" :normalizer="normalizerSourceType" :options="sourceTypeOptions"
                      placeholder="请选择样本源类型" size="small" style="width: 220px"
          />
        </el-form-item>
        <el-form-item label="采样时间" prop="samplingRange">
          <el-date-picker
            v-model="queryParams.samplingRange"
            :picker-options="pickerOptions"
            align="right"
            end-placeholder="结束日期"
            range-separator="至"
            start-placeholder="开始日期"
            type="datetimerange"
            value-format="yyyy-MM-dd HH:mm:ss"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item>
          <el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
          <el-button v-if="canCreate" v-hasPermi="['biobank:sample:add']" icon="el-icon-plus" plain size="mini"
                     type="primary" @click="handleCreate"
          >创建新样本
          </el-button>
        </el-form-item>
      </el-form>

      <el-table ref="table" v-loading="loading" :data="sampleList" height="600"
                size="small" @select="handleSelect" @selection-change="handleSelectionChange"
      >
        <el-table-column :selectable="checkSelectable" align="center" type="selection" width="55"/>
        <el-table-column align="center" label="样本复份编号" min-width="110" prop="sampBackupCode"/>
        <el-table-column align="center" label="样本类型" prop="sampTypeName"/>
        <el-table-column align="center" label="样本源名称" prop="sampSourceName"/>
        <el-table-column align="center" label="采样时间" prop="samplingTime" width="180">
          <template slot-scope="scope">
            <span>{{ parseTime(scope.row.samplingTime, '{y}-{m}-{d}') }}</span>
          </template>
        </el-table-column>
        <el-table-column align="center" label="样本位置" prop="sampLocation" width="300"/>
        <el-table-column align="center" label="样本源类型" prop="sampSourceTypeName"/>
        <el-table-column align="center" label="样本组" prop="sampGroupName"/>
        <el-table-column align="center" label="样本量" prop="sampQuantity"/>
        <el-table-column align="center" label="样本单位" prop="sampUnit"/>
        <el-table-column :formatter="sampStateFormat" align="center" label="样本状态" prop="sampState"/>
        <el-table-column align="center" label="冻融次数" prop="sampFreezeThawCount"/>
        <el-table-column align="center" label="条码/二维码" prop="qrCode"/>
      </el-table>

      <pagination
        v-show="total>0"
        :limit.sync="queryParams.pageSize"
        :page.sync="queryParams.pageNum"
        :total="total"
        @pagination="getList"
      />

      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="confirmPick">确 定</el-button>
        <el-button @click="cancelPick">取 消</el-button>
      </div>

      <!-- 创建新样本 -->
      <el-dialog :visible.sync="createOpen" append-to-body title="创建新样本" width="60%">
        <el-form ref="createForm" :model="createForm" :rules="createRules" label-width="96px">
          <el-row>
            <el-col :span="12">
              <el-form-item label="样本源编号" prop="sourceCode">
                <el-input v-model="createForm.sourceCode" placeholder="请输入样本源编号" @change="getSourceDetail"/>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="样本源名称" prop="sourceName">
                <el-input v-model="createForm.sourceName" placeholder="请输入样本源名称"/>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="随访状态" prop="followState">
                <el-select
                  v-model="createForm.followState"
                  clearable
                  placeholder="随访状态"
                  size="small"
                  style="width: 100%"
                >
                  <el-option
                    v-for="dict in followStateOptions"
                    :key="dict.dictValue"
                    :label="dict.dictLabel"
                    :value="dict.dictValue"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="样本源类型" prop="sourceTypeId">
                <treeselect v-model="createForm.sourceTypeId" :normalizer="normalizerSourceType"
                            :options="sourceTypeOptions" placeholder="请选择样本源类型"
                            @select="sourceTypeSelect"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="样本源描述" prop="sourceDesc">
                <el-input v-model="createForm.sourceDesc" :rows="2" placeholder="请输入样本源描述" type="textarea"></el-input>
              </el-form-item>
              <el-input v-if="false" v-model="createForm.formKey" placeholder="请输入自定义表单key"/>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <div
                v-for="(domain, index) in createForm.formJson"
                :key="index"
                :label="domain.controlLable"
              >
                <parser ref="formCustom" :form-conf="domain.json"/>
              </div>
            </el-col>
          </el-row>
          <file-upload :value="createForm.attaches" style="margin-top: 16px" @fileEvent="fileUploadEvent"></file-upload>
          <el-divider><i class="el-icon-s-promotion"></i></el-divider>
          <el-row>
            <el-col :span="12">
              <el-form-item label="样本编号" prop="sampBackupCode">
                <el-input v-model="createForm.sampCode" placeholder="样本编号"/>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="样本类型" prop="sampTypeId">
                <treeselect v-model="createForm.sampTypeId" :normalizer="normalizerSampType"
                            :options="sampleTypeOptions" placeholder="请选择样本类型"
                            @select="sampleTypeSelect"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="样本组" prop="sampGroupId">
                <treeselect v-model="createForm.sampGroupId" :normalizer="normalizerSampGroup"
                            :options="sampleGroupOptions" placeholder="请选择样本组"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="样本复份数" prop="sampBackupCount">
                <el-input-number v-model="createForm.sampBackupCount" :min="1" controls-position="right"
                                 placeholder="请输入样本复份数" style="width: 100%"
                />
              </el-form-item>
            </el-col>
            <!--            <el-col :span="12">-->
            <!--              <el-form-item label="冻存管类型" prop="tubeType">-->
            <!--                <el-select-->
            <!--                  v-model="createForm.tubeType"-->
            <!--                  placeholder="冻存管类型"-->
            <!--                  clearable-->
            <!--                  size="small"-->
            <!--                  style="width: 100%"-->
            <!--                >-->
            <!--                  <el-option-->
            <!--                    v-for="dict in tubeTypeOptions"-->
            <!--                    :key="dict.dictValue"-->
            <!--                    :label="dict.dictLabel"-->
            <!--                    :value="dict.dictValue"-->
            <!--                  />-->
            <!--                </el-select>-->
            <!--              </el-form-item>-->
            <!--            </el-col>-->
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="样本量" prop="sampQuantity">
                <el-input v-model="createForm.sampQuantity" placeholder="请输入样本量"/>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="样本单位" prop="sampUnit">
                <el-input v-model="createForm.sampUnit" placeholder="请输入样本单位"/>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="采样时间" prop="samplingTime">
                <el-date-picker v-model="createForm.samplingTime" clearable
                                placeholder="选择采样时间"
                                size="small"
                                style="width: 100%"
                                type="datetime"
                                value-format="yyyy-MM-dd HH:mm:ss"
                >
                </el-date-picker>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button type="primary" @click="submitCreateForm">确 定</el-button>
          <el-button @click="cancelCreate">取 消</el-button>
        </div>
      </el-dialog>
    </el-dialog>
  </div>
</template>

<script>
import { createSample, listSample } from '@/api/biobank/sample'
import { getSampleType, listSampleType } from '@/api/biobank/sampleType'
import { listSampleGroup } from '@/api/biobank/sampleGroup'
import { listSourceType } from '@/api/biobank/sourceType'
import { getSourceByCode } from '@/api/biobank/source'
import { formJsonShow } from '@/api/tool/form'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import Parser from 'form-gen-parser'
import FileUpload from '@/components/FileUpload'

export default {
  name: 'SamplePick',
  components: {
    Treeselect,
    Parser,
    FileUpload
  },
  props: {
    value: {
      type: Array,
      default: () => []
    },
    open: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: '挑选样本'
    },
    // 查询的样本状态
    sampState: {
      type: String,
      default: '1'
    },
    // 是否单选
    singleChoice: {
      type: Boolean,
      default: false
    },
    // 是否显示创建样本按钮
    canCreate: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 样本复份 表格数据
      sampleList: [],
      // 选中的样本复份
      selectSamples: undefined,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 20,
        orderByColumn: 'createTime',
        isAsc: 'DESC',
        sampBackupCode: undefined,
        sampState: undefined,
        sampTypeId: undefined,
        sampGroupId: undefined,
        sourceCode: undefined,
        sourceName: undefined,
        sourceTypeId: undefined,
        samplingRange: undefined,
        stockState: '0'
      },
      // 样本类型 树选项
      sampleTypeOptions: [],
      // 样本组 树选项
      sampleGroupOptions: [],
      // 样本源类型 树选项
      sourceTypeOptions: [],
      // 样本状态
      sampStateOptions: [],
      // 创建样本弹出层
      createOpen: false,
      // 创建样本表单参数
      createForm: {},
      // 创建新样本表单校验
      createRules: {
        sourceCode: { required: true, trigger: 'blur', message: '样本源编号不能为空' },
        sourceName: { required: true, trigger: 'blur', message: '样本源名称不能为空' },
        sourceTypeId: { required: true, trigger: 'change', message: '样本源类型不能为空' },
        sampTypeId: { required: true, trigger: 'change', message: '样本类型不能为空' },
        sampGroupId: { required: true, trigger: 'change', message: '样本组不能为空' },
        sampBackupCount: { required: true, trigger: 'blur', message: '样本复份数不能为空' }
        // tubeType: { required: true, trigger: 'change', message: '冻存管类型不能为空' },
      },
      // 随访状态
      followStateOptions: [],
      // 冻存管类型
      tubeTypeOptions: [],
      pickerOptions: {
        shortcuts: [{
          text: '最近一周',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近一个月',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近三个月',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            picker.$emit('pick', [start, end])
          }
        }]
      }
    }
  },
  created() {
    this.getDicts('sample_state').then(response => {
      this.sampStateOptions = response.data
    })
    this.queryParams.sampState = this.sampState
    this.getSampleTypeList()
    this.getSampleGroupList()
    this.getSourceTypeList()
    this.getList()
    if (this.canCreate) {
      this.getDicts('follow_state').then(response => {
        this.followStateOptions = response.data
      })
      this.getDicts('tube_type').then(response => {
        this.tubeTypeOptions = response.data
      })
    }
  },
  watch: {
    sampState(newValue, oldValue) {
      if (newValue && newValue.length > 0) {
        this.queryParams.sampState = newValue
        this.getList()
      }
    }
  },
  methods: {
    // 创建样本源附件上传子组件回调
    fileUploadEvent(fileList) {
      this.createForm.attaches = fileList
    },
    checkSelectable(row) {
      let isChecked = true
      // 处于其他流程中的样本不允许再进入流程
      if (row.stockState === this.GLOBAL.STOCK_STATE.PROCESS) {
        isChecked = false
      }
      // 已经选择过一次的样本不允许再次选中
      if (this.value && this.value.length > 0) {
        this.value.forEach(item => {
          if (item.sampBackupId === row.sampBackupId) {
            isChecked = false
          }
        })
      }
      return isChecked
    },
    /** 查询样本类型 列表 */
    getSampleTypeList() {
      listSampleType().then(response => {
        this.sampleTypeOptions = this.handleTree(response.data, 'sampTypeId', 'parentId')
      })
    },
    /** 转换样本类型 数据结构 */
    normalizerSampType(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.sampTypeId,
        label: node.sampTypeName,
        children: node.children
      }
    },
    /** 查询样本组 列表 */
    getSampleGroupList() {
      listSampleGroup(this.queryParams).then(response => {
        this.sampleGroupOptions = this.handleTree(response.data, 'sampGroupId', 'parentId')
      })
    },
    /** 转换样本组 数据结构 */
    normalizerSampGroup(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.sampGroupId,
        label: node.sampGroupName,
        children: node.children
      }
    },
    /** 查询样本源类型 列表 */
    getSourceTypeList() {
      listSourceType(this.queryParams).then(response => {
        this.sourceTypeOptions = this.handleTree(response.data, 'sourceTypeId', 'parentId')
      })
    },
    /** 转换样本源类型 数据结构 */
    normalizerSourceType(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.sourceTypeId,
        label: node.sourceTypeName,
        children: node.children
      }
    },
    /** 样本状态状态字典翻译 */
    sampStateFormat(row, column) {
      return this.selectDictLabel(this.sampStateOptions, row.sampState)
    },
    /** 查询样本复份 列表 */
    getList() {
      this.loading = true
      listSample(this.queryParams).then(response => {
        this.sampleList = response.rows
        this.total = response.total
        this.loading = false
      })
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm('queryForm')
      this.handleQuery()
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      if (!this.singleChoice) {
        this.selectSamples = selection
      }
    },
    handleSelect(selection, row) {
      if (this.singleChoice) {
        this.$refs.table.clearSelection()
        if (row) {
          this.$refs.table.toggleRowSelection(row, true)
          this.selectSamples = row
        }
      }
    },
    // 样本对话框取消按钮
    cancelPick() {
      this.$emit('onClose')
    },
    // 样本对话框确定按钮
    confirmPick() {
      this.$emit('onConfirm', this.selectSamples)
    },
    // 新增按钮操作
    handleCreate() {
      this.createReset()
      this.createOpen = true
    },
    /** 获取样本源详情 */
    getSourceDetail(content) {
      getSourceByCode(content).then(response => {
        if (response.data && Object.keys(response.data).length > 0) {
          this.createForm.sourceId = response.data.sourceId
          this.createForm.sourceName = response.data.sourceName
          this.createForm.sourceDesc = response.data.sourceDesc
          this.createForm.attaches = response.data.attaches
          this.createForm.followState = response.data.followState
          this.createForm.sourceTypeId = response.data.sourceTypeId
          this.createForm.formKey = response.data.formKey
          this.createForm.formDesc = response.data.formDesc
          this.createForm.formData = response.data.formData
          this.showFormJson(this.createForm.formKey)
        } else {
          this.createForm.sourceId = undefined
          this.createForm.sourceName = undefined
          this.createForm.sourceDesc = undefined
          this.createForm.followState = undefined
          this.createForm.sourceTypeId = undefined
          this.createForm.formKey = undefined
          this.createForm.formDesc = undefined
          this.createForm.formData = undefined
        }
      })
    },
    // 样本源类型下拉框选择事件
    sourceTypeSelect(node, instanceId) {
      this.createForm.formKey = node.formKey
      this.showFormJson(node.formKey)
    },
    // 渲染动态表单
    showFormJson(formKey) {
      formJsonShow(formKey).then(response => {
        let formJson = []
        for (let oncekey in response.data) {
          let datas = response.data[oncekey]
          if (datas) {
            for (let i = 0; i < datas.length; i++) {
              let once = datas[i]
              if (/^{/.test(once)) {
                formJson.push({
                  json: JSON.parse(once)
                })
              }
            }
          }
        }
        this.$set(this.createForm, 'formJson', formJson)
        if (this.createForm.formData != undefined) {
          this.fillFormData(this.createForm.formJson[0].json, JSON.parse(this.createForm.formData))
          this.$set(this.createForm, 'formJson', formJson)
        }
      })
    },
    // 动态表单值回写
    fillFormData(form, data) {
      form.fields.map(item => {
        if (item.__vModel__) {
          const val = data[item.__vModel__]
          if (val) {
            item.__config__.defaultValue = val
          }
          return item
        } else {
          if (item.__config__ && item.__config__.children && item.__config__.children.length > 0) {
            item.__config__.children.forEach(child => {
              const childVal = data[child.__vModel__]
              if (childVal) {
                child.__config__.defaultValue = childVal
              }
            })
            return item
          }
        }
      })
    },
    // 样本类型下拉框选择事件
    sampleTypeSelect(node, instanceId) {
      getSampleType(node.sampTypeId).then(response => {
        if (response.data) {
          this.$set(this.createForm, 'sampQuantity', response.data.sampTypeDefaultQuantity)
          this.createForm.sampUnit = response.data.sampTypeDefaultUnit
          this.createForm.sampBackupCount = response.data.sampTypeDefaultDuplqty
        }
      })
    },
    createReset() {
      this.createForm = {
        sourceId: undefined,
        sourceCode: undefined,
        sourceName: undefined,
        sourceDesc: undefined,
        attaches: undefined,
        followState: undefined,
        sourceTypeId: undefined,
        formKey: undefined,
        formJson: undefined,
        formDesc: undefined,
        formData: undefined,
        sampTypeId: undefined,
        sampGroupId: undefined,
        sampQuantity: undefined,
        sampUnit: undefined,
        sampBackupCount: undefined,
        tubeType: undefined,
        samplingTime: undefined,
        formDataSaveDto: undefined
      }
      this.resetForm('createForm')
    },
    submitCreateForm() {
      if (this.createForm.formKey) {
        let custFormRef = this.$refs.formCustom[0]
        let custForm = custFormRef.$refs[custFormRef.formConf.formRef]
        let custData = custFormRef[custFormRef.formConf.formModel]
        let custDesc = {}
        for (let onceForm of this.createForm.formJson) {
          for (let onceField of onceForm.json.fields) {
            if (onceField.__vModel__) {
              custDesc[onceField.__vModel__] = onceField.__config__.label
            } else {
              if (onceField.__config__ && onceField.__config__.children && onceField.__config__.children.length > 0) {
                onceField.__config__.children.forEach(child => {
                  custDesc[child.__vModel__] = child.__config__.label
                })
              }
            }
          }
        }
        let formDataDto = { data: custData, desc: custDesc }
        // 自定义表单的核验
        custForm.validate(e => {
          if (e) {
            this.createForm.formDataSaveDto = formDataDto
          }
        })
      }

      this.$refs['createForm'].validate(valid => {
        if (valid) {
          createSample(this.createForm).then(response => {
            this.msgSuccess('新增成功')
            this.createOpen = false
            this.createReset()
            this.getList()
          })
        }
      })
    },
    cancelCreate() {
      this.createOpen = false
      this.createReset()
    }
  }
}
</script>
<style scoped>
.el-form-item {
  margin-bottom: 7px;
}

/deep/ .el-dialog__body {
  padding: 10px;
}
</style>
